# 11:40 - 11:57 


class Process(object):
	def __init__(self, name, delta, arrival=0):
		self.name = name
		self.delta = delta
		self.arrival = arrival
	
	def run(self):
		print(self.name)

class Scheduler(object):
	def __init__(self, processes, algo_class):
		self.algo = algo_class(processes)
	def scheduling(self):
		for process in self.algo:
			process.run()

def slice_first(l):
	return l[0],l[1:]

class Iterable(object):
	def __iter__(self):
		return self

class Fifo(Iterable):
	def __init__(self, processes):
		self.processes = sorted(processes, key=lambda x:x.arrival)
	def __next__(self):
		try:
			p, self.processes = slice_first(self.processes)
			return p
		except:
			raise StopIteration

class RoundRobin(Iterable):
	def __init__(self, processes):
		self.processes = processes
		self.quantum = 5
	def __next__(self):
		try:
			p, others = slice_first(self.processes)
			p.delta -= self.quantum
			self.processes = others+[p] if p.delta>0 else others
			return p
		except:
			raise StopIteration


if __name__ == "__main__":
	pl = [Process("one", 10), Process("two", 3, 5), Process("three", 15), \
              Process("four", 30, 5), Process("five", 10), Process("six", 6, 10), \
              Process("seven", 10), Process("eight", 25, 5)]
	line = '-'*20
	print("{0}fifo scheduling".format(line))
	s = Scheduler(pl, Fifo)
	s.scheduling()
	print("{0}round-robin scheduling".format(line))
	s = Scheduler(pl, RoundRobin)
	s.scheduling()

